package lyx.totalexample.imagesearch.controller;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lyx.totalexample.imagesearch.entity.ImageSave;
import lyx.totalexample.imagesearch.entity.Result;
import lyx.totalexample.imagesearch.service.ImageSaveService;
import lyx.totalexample.imagesearch.util.imageInitUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;

/**
 * <p>
 * 图片存储表 前端控制器
 * </p>
 *
 * @author lyx
 * @since 2025-10-10
 */
@RestController
@RequestMapping("/image")
@Tag(name = "图片存储")
@RequiredArgsConstructor
public class ImageSaveController {

    private final ImageSaveService imageSaveService;

    private final imageInitUtil imageInitUtil;

    @PostMapping("/upload")
    @Operation(summary = "上传图片", description = "上传图片到服务器")
    public Result uploadImage(@RequestParam("file") MultipartFile file){

        try {
            String imgUrl = imageInitUtil.uploadFile(file);
            Map<String,String> resultMap = new HashMap<>();
            resultMap.put("url",imgUrl);
            return Result.success(resultMap);
        } catch (Exception e) {
            return Result.fail(500, "上传失败：" + e.getMessage());
        }
    }

    @GetMapping("/init")
    @Operation(summary = "初始化图片", description = "初始化图片到数据库")
    public Result initImage(){
        try {
            imageInitUtil.init();
            return Result.success("初始化成功");
        } catch (Exception e) {
            return Result.fail(500, "初始化失败：" + e.getMessage());
        }
    }

    @PostMapping("/saveImage")
    @Operation(summary = "保存图片", description = "保存图片信息")
    public Result saveImage(@RequestBody ImageSave image){
        boolean save = imageSaveService.save(image);
        if(save) {
            return Result.success("添加成功");
        } else {
            return Result.fail("添加失败");
        }
    }

    @GetMapping("/getAll")
    @Operation(summary = "获取所有图片", description = "获取数据库中所有图片信息")
    @Parameters({
            @Parameter(name = "pageNum", description = "页码，从1开始", required = true),
            @Parameter(name = "pageSize", description = "每页显示的记录数", required = true),
            @Parameter(name = "keyWord", description = "搜索关键词", required = false)
    })
    public Result getAllImage(@RequestParam(value = "pageNum",defaultValue = "1") int pageNum,
                              @RequestParam(value = "pageSize",defaultValue = "10") int pageSize,
                              @RequestParam(value = "keyWord",required = false) String keyWord){
        return Result.success(imageSaveService.page(new Page<>(pageNum, pageSize),
                Wrappers.lambdaQuery(ImageSave.class)
                        .like(StringUtils.isNotBlank(keyWord),ImageSave::getImageName,keyWord)));
    }

    @GetMapping("/getImage")
    @Operation(summary = "获取图片", description = "根据图片路径获取图片")
    @Parameter(name = "path", description = "图片路径", required = true)
    public ResponseEntity getImage(@RequestParam("path") String path){
        try {
            String decodedPath = URLDecoder.decode(path, StandardCharsets.UTF_8.name());
            // 3. 构建完整的图片文件路径
            Path imagePath = Paths.get(decodedPath).normalize();
            // 4. 安全检查：防止路径遍历攻击
            if (!imagePath.startsWith(Paths.get(decodedPath))) {
                return new ResponseEntity<>(HttpStatus.FORBIDDEN);
            }
            // 5. 检查文件是否存在且是一个文件
            File imageFile = imagePath.toFile();
            if (!imageFile.exists() || !imageFile.isFile()) {
                return new ResponseEntity<>(HttpStatus.NOT_FOUND);
            }
            // 6. 确定图片的MIME类型
            String contentType = Files.probeContentType(imagePath);
            if (contentType == null) {
                contentType = "application/octet-stream";
            }
            Resource resource = new FileSystemResource(imageFile);

            return ResponseEntity.ok()
                    .contentType(MediaType.parseMediaType(contentType))
                    .header(HttpHeaders.CONTENT_DISPOSITION,
                            "inline; filename=\"" + imageFile.getName() + "\"")
                    .body(resource);
        } catch (UnsupportedEncodingException e) {
            return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
        } catch (Exception e) {
            return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }
}
